﻿#pragma once
#if defined(_MSC_VER)
	#define _CRT_SECURE_NO_WARNINGS
#endif


//#include <stdio.h>
#include <iostream>
#include <memory>
#include <cstdlib>    // malloc, free
#include <new>        // std::bad_alloc

struct AllocationMetrics { // 全局结构体，记录分配和释放的内存大小
	size_t total_allocated = 0; // 总分配的内存大小, 单位：最大 32 位字节
	size_t total_freed = 0;

	size_t current_usage() const { // 当前内存使用情况
		return total_allocated - total_freed;
	}
};
extern AllocationMetrics allocation_main;


/*
标准库中的 operator new 有多个重载版本，但最基本的版本是：
	void* operator new(size_t size) noexcept(false);

然而，标准库中的 operator delete 和 operator delete[] 的最基本的签名是：
	void operator delete(void* ptr) noexcept;
	void operator delete[](void* ptr) noexcept;
	但是 operator delete 和 operator delete[] 也支持 size_t 参数，但并不一定会被调用。
*/
void* operator new(size_t size) {
	// 重载 new 运算符，这里并不是一个很好的重载
	if (size == 0)
		size = 1; // 根据C++标准，0字节的分配应该返回一个非空指针
	//if (size == 0)
	//	return nullptr;
	allocation_main.total_allocated += size;
	void* ptr = malloc(size);
	if (ptr == nullptr)
		throw std::bad_alloc(); // 抛出异常而不是返回 nullptr
	return ptr;
}

void operator delete(void* ptr
#if defined(WIN32) || defined(_WIN32) || defined(__NT__) || defined(WIN64) || defined(_WIN64)

#else
					 , size_t size
#endif
) noexcept {
	// 重载 delete 运算符，这里并不是一个很好的重载
#if defined(WIN32) || defined(_WIN32) || defined(__NT__) || defined(WIN64) || defined(_WIN64)
	allocation_main.total_freed += _msize(ptr); // 使用 _msize 获取分配的内存大小（仅适用于 Windows）
#else
	allocation_main.total_freed += size;
#endif
	free(ptr);
}

void operator delete[](void* ptr
#if defined(WIN32) || defined(_WIN32) || defined(__NT__) || defined(WIN64) || defined(_WIN64)

#else
					   , size_t size
#endif
) noexcept {
	// 重载 delete 运算符，这里并不是一个很好的重载
#if defined(WIN32) || defined(_WIN32) || defined(__NT__) || defined(WIN64) || defined(_WIN64)
	allocation_main.total_freed += _msize(ptr); // 使用 _msize 获取分配的内存大小（仅适用于 Windows）
#else
	allocation_main.total_freed += size;
#endif
	free(ptr);
}

void print_memory_usage() { // 打印分配的内存大小
	std::cout << "Total allocated: " << allocation_main.current_usage() << " bytes\n";
}


// 宏定义
#define print_start(str) std::cout << " ----------------- " << str << " Start ------------------------\n";
#define print_end(str) std::cout << " ----------------- " << str << " End ------------------------\n\n\n";